function Set(){
    this.items = {}
    this.length = 0

    Set.prototype.has = function(item){
        return this.items.hasOwnProperty(item)
    }

    Set.prototype.add = function(item){
        if(!this.has(item)){
            this.items[item] = item
            this.length++
            return true
        }
        return false
    }

    Set.prototype.remove = function(item){
        if(this.has(item)){
            delete this.items[item]
            this.length--
            return true
        }
        return false
    }

    Set.prototype.clear = function(){
        this.items = {}
    }

    Set.prototype.values = function(){
        return Object.keys(this.items)
    }

    Set.prototype.union = function(otherSet){
        let unionSet = new Set()
        for(let item of otherSet.values()){
            unionSet.add(item)
        }
        for(let item of this.values()){
            unionSet.add(item)
        }
        return unionSet
    }

    Set.prototype.intersection = function(otherSet){
        let intersectionSet = new Set()
        for(let item of otherSet.values()){
            if(this.has(item)){
                intersectionSet.add(item)
            }
        }
        return intersectionSet
    }

    Set.prototype.difference = function(otherSet){
        let differenceSet = new Set()
        for(let item of this.values()){
            if(!otherSet.has(item)){
                differenceSet.add(item)
            }
        }
        return differenceSet
    }

    Set.prototype.subSet = function(otherSet){
        return this.values().every(item => otherSet.has(item))
    }
}

let s = new Set()
let s1 = new Set()
let s2 = new Set()
s.add('a')
s.add('b')
s.add('c')
s1.add('a')
s1.add('d')
s1.add('c')
s2.add('a')
s2.add('c')
let union = s.union(s1)
